<?php
class lib_Text
{
	var $viet = true;

	function lib_Text ()
	{
		// array used to figure what number to decrement from character order value 
		// according to number of characters used to map unicode to ascii by utf-8
		$this->decrement[4] = 240;
		$this->decrement[3] = 224;
		$this->decrement[2] = 192;
		$this->decrement[1] = 0;

		// the number of bits to shift each charNum by
		$this->shift[1][0] = 0;
		$this->shift[2][0] = 6;
		$this->shift[2][1] = 0;
		$this->shift[3][0] = 12;
		$this->shift[3][1] = 6;
		$this->shift[3][2] = 0;
		$this->shift[4][0] = 18;
		$this->shift[4][1] = 12;
		$this->shift[4][2] = 6;
		$this->shift[4][3] = 0;

		// vietchas: [a, a^, a(, e, e^, i, o, o^, o+, u, u+, y, A, A^,...U+, Y]
		$this->vietchar[0] = array (
			97, 226, 259, 101, 234, 105, 111, 244, 417, 117, 432, 121, 
			65, 194, 258, 69, 202, 73, 79, 212, 416, 85, 431, 89
		);
		$this->vietchar[1] = array (	// huyen
			224, 7847, 7857, 232, 7873, 236, 242, 7891, 7901, 249, 7915, 7923,
			192, 7846, 7856, 200, 7872, 204, 210, 7890, 7900, 217, 7914, 7922
		);
		$this->vietchar[2] = array (	// hoi
			7843, 7849, 7859, 7867, 7875, 7881, 7887, 7893, 7903, 7911, 7917, 7927,
			7842, 7848, 7858, 7866, 7874, 7880, 7886, 7892, 7902, 7910, 7916, 7926
		);
		$this->vietchar[3] = array (	// nga
			227, 7851, 7861, 7869, 7877, 297, 245, 7895, 7905, 361, 7919, 7929,
			195, 7850, 7860, 7868, 7876, 296, 213, 7894, 7904, 360, 7918, 7928
		);
		$this->vietchar[4] = array (	// sac
			225, 7845, 7855, 233, 7871, 237, 243, 7889, 7899, 250, 7913, 253, 
			193, 7844, 7854, 201, 7870, 205, 211, 7888, 7898, 218, 7912, 221
		);
		$this->vietchar[5] = array (	// nang
			7841, 7853, 7863, 7865, 7879, 7883, 7885, 7897, 7907, 7909, 7921, 7925,
			7840, 7852, 7862, 7864, 7878, 7882, 7884, 7896, 7906, 7908, 7920, 7924
		);
		$this->vietrepl_letter = array (
			'a', 'azz', 'az', 'e', 'ez', 'i', 'o', 'oz', 'ozz', 'u', 'uz', 'y',
			'A', 'AZZ', 'AZ', 'E', 'EZ', 'I', 'O', 'OZ', 'OZZ', 'U', 'UZ', 'Y'
		);
		$this->vietchar_d = array (100, 273, 68, 272);	// d, D
		$this->vietrepl_d = array ('d', 'dz', 'D', 'DZ');
		$this->vietrepl_accent = array ('', '1', '2', '3', '4', '5');
		$this->unified = array(208=>272, 240=>273);
	}

	function to_unicode($txt)
	{
		/*
		Table 1. UTF-8 encoding

		bytes	bits	representation 
		1		7		0bbbbbbb 
		2		11		110bbbbb 10bbbbbb 
		3		16		1110bbbb 10bbbbbb 10bbbbbb 
		4		21		11110bbb 10bbbbbb 10bbbbbb 10bbbbbb 

		Each 'b' represents a bit that can be used to store character data.

		The part converting UTF-8 at www.php.net/manual/en/function.utf8-decode.php
		by ronen@greyzone.com, 01-Mar-2002 05:37
		*/
		$out = array();
		$n = strlen($txt);
		for ($i=0; $i<$n; $i++)
		{
			$j = ord($txt[$i]);
			if ($j < 128) $out[] = $j;
			else if ($j>>5 == 6)
			{
				$b1 = ($j & 31);
				$b2 = (ord($txt[++$i]) & 63);
				$out[] = ($b1 * 64) + $b2;
			}
			else if ($j>>4 == 14)
			{
				$b1 = ($j & 31);
				$b2 = (ord($txt[++$i]) & 63);
				$b3 = (ord($txt[++$i]) & 63);
				$out[] = ((($b1 * 64) + $b2) * 64) + $b3;
			}
			else if ($j>>3 == 30)
			{
				$b1 = ($j & 31);
				$b2 = (ord($txt[++$i]) & 63);
				$b3 = (ord($txt[++$i]) & 63);
				$b4 = (ord($txt[++$i]) & 63);
				$out[] = ((((($b1 * 64) + $b2) * 64) + $b3) * 64) + $b4;
			}
		}
		return $out;
	}

	/*
	This a so cool function. Easy to sort, easy to search, and standard!
	For example: tr*o*`ng become truzozzng1

	It works with a paragraph of text, in any language!
	*/
	function txt2std($txt)
	{
		$text = array(
			48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
			65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
			97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
			192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
			217, 218, 219, 220, 221, 
			224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
			249, 250, 251, 252, 253);

		$txt = str_replace("\n", " ", $txt);
		$out = $this->to_unicode($txt);
		$out[] = 32;
		$out[] = 65;
		$std = array();
		$word = '';
		$accent = 0;

		for ($k=0,$n=count($out); $k<$n; $k++)
		{
			while (($out[$k]<=255) && (!in_array($out[$k], $text)))
			{
				if (!empty($word))
				{
					$std[] = $word . ($accent==0 ? '' : $accent);
					$word = '';
					$accent = 0;
				}
				$k++;
			}

			$found = false;
			$code = isset($this->unified[$out[$k]]) ? $this->unified[$out[$k]] : $out[$k];
			for ($i=0; $i<=5; $i++)
			{
				$m = array_search($code, $this->vietchar[$i]);
				if ($m !== false)
				{
					$found = true;
					$letter = $this->vietrepl_letter[$m];
					if ($this->vietrepl_accent[$i]) $accent = $this->vietrepl_accent[$i];
					break;
				}
			}
			$m = array_search($code, $this->vietchar_d);
			if ($m !== false)
			{
				$found = true;
				$letter = $this->vietrepl_d[$m];
			}
			if (! $found)
			{
				$letter = ($code < 256) ? chr($code) : '_';
			}
			$word .= $letter;
		}
		return implode(' ', $std);
	}

	function no_accent($txt)
	{
		$out = $this->to_unicode($txt);
		$txt = '';
		$from = array(97, 226, 259, 101, 234, 105, 111, 244, 417, 117, 432, 121, 65, 194, 258, 69, 202, 73, 79, 212, 416, 85, 431, 89,
			224, 7847, 7857, 232, 7873, 236, 242, 7891, 7901, 249, 7915, 7923, 192, 7846, 7856, 200, 7872, 204, 210, 7890, 7900, 217, 7914, 7922,
			7843, 7849, 7859, 7867, 7875, 7881, 7887, 7893, 7903, 7911, 7917, 7927, 7842, 7848, 7858, 7866, 7874, 7880, 7886, 7892, 7902, 7910, 7916, 7926,
			227, 7851, 7861, 7869, 7877, 297, 245, 7895, 7905, 361, 7919, 7929, 195, 7850, 7860, 7868, 7876, 296, 213, 7894, 7904, 360, 7918, 7928,
			225, 7845, 7855, 233, 7871, 237, 243, 7889, 7899, 250, 7913, 253, 193, 7844, 7854, 201, 7870, 205, 211, 7888, 7898, 218, 7912, 221,
			7841, 7853, 7863, 7865, 7879, 7883, 7885, 7897, 7907, 7909, 7921, 7925, 7840, 7852, 7862, 7864, 7878, 7882, 7884, 7896, 7906, 7908, 7920, 7924,
			100, 273, 68, 272);
		$to = 'aaaeeiooouuyAAAEEIOOOUUYaaaeeiooouuyAAAEEIOOOUUYaaaeeiooouuyAAAEEIOOOUUYaaaeeiooouuyAAAEEIOOOUUYaaaeeiooouuyAAAEEIOOOUUYaaaeeiooouuyAAAEEIOOOUUYddDD';
		for ($k=0,$n=count($out); $k<$n; $k++)
		{
			$i=array_search($out[$k], $from);
			$txt .= ($i===false)? chr($out[$k]) : $to[$i];
		}
		return $txt;
	}

	function name2std($name)
	{
		$name = explode(' ', $this->txt2std($name));
		array_unshift($name, array_pop($name));
		return implode(' ', $name);
	}
}
?>